package com.squirrel.serialportcore.machine.creator;

import com.squirrel.serialportcore.entity.model.BindingModel;
import com.squirrel.serialportcore.entity.model.ExchangeModel;
import com.squirrel.serialportcore.entity.model.QueueModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.Properties;

/**
 * 消息队列创建者
 *
 * @author Squbi
 * @date 2021/3/16 16:24
 */
@Component
public class MessageQueueCreator {
    private static final Logger logger = LoggerFactory.getLogger(MessageQueueCreator.class);

    private RabbitAdmin rabbitAdmin;

    MessageQueueCreator(RabbitAdmin rabbitAdmin) {
        this.rabbitAdmin = rabbitAdmin;
    }

    public boolean queueIsExist(String queueName) {
        Properties properties = rabbitAdmin.getQueueProperties(queueName);
        logger.debug(" -debug- 获取消息队列 {} 其属性 {}", queueName, properties);
        return properties != null;
    }

    public boolean deleteQueue(String queueName) {
        return rabbitAdmin.deleteQueue(queueName);
    }

    public Queue create(QueueModel queueModel) {
        Queue queue = createQueue(queueModel);
        logger.debug(" -debug- 正在创建Queue -> {}", queue);
        rabbitAdmin.declareQueue(queue);
        return queue;
    }

    public Exchange create(ExchangeModel exchangeModel) {
        Exchange exchange = createExchange(exchangeModel);
        logger.debug(" -debug- 正在创建Exchange -> {}", exchange);
        rabbitAdmin.declareExchange(exchange);
        return exchange;
    }

    public Binding create(BindingModel bindingModel) {
        Binding binding = createBinding(bindingModel);
        logger.debug(" -debug- 正在创建Binding -> {}", binding);
        rabbitAdmin.declareBinding(binding);
        return binding;
    }

    /**
     * -------------------------------------------
     *
     * @author Squbi
     * @date 2021/3/16 17:44
     */

    public Queue createQueue(QueueModel queueModel) {
        return new Queue(queueModel.getQueueName(), queueModel.isDurable()
                , queueModel.isExclusive(), queueModel.isAutoDelete());
    }

    public Exchange createExchange(ExchangeModel exchangeModel) {
        ExchangeBuilder builder;
        String name = exchangeModel.getExchangeName();
        switch (exchangeModel.getExchangeType()) {
            case TOPIC:
                builder = ExchangeBuilder.topicExchange(name);
                break;
            case DIRECT:
                builder = ExchangeBuilder.directExchange(name);
                break;
            case FANOUT:
                builder = ExchangeBuilder.fanoutExchange(name);
                break;
            case HEADERS:
                builder = ExchangeBuilder.headersExchange(name);
                break;
            default:
                return null;
        }
        if (exchangeModel.isAutoDelete()) {
            builder.autoDelete();
        }
        builder.durable(exchangeModel.isDurable());
        return builder.build();
    }

    public Binding createBinding(BindingModel bindingModel) {
        BindingBuilder.GenericArgumentsConfigurer configurer =
                BindingBuilder.bind(bindingModel.getQueue())
                        .to(bindingModel.getExchange())
                        .with(bindingModel.getRouting());
        Map<String, Object> args = bindingModel.getArgs();
        return args == null ? configurer.noargs() : configurer.and(args);
    }
}
